from flask import Blueprint
from flask import render_template, url_for, redirect, flash, request, current_app
from flask_login import login_user, logout_user, login_required, current_user
from sqlalchemy import select
from learn_flask.extensions import db
from learn_flask.models import User, Movie


# 创建主页面蓝图
# 蓝图用于组织路由，将相关的视图函数组织在一起
# 'main'是蓝图名称，'__name__'是蓝图所在模块
main_bp = Blueprint('main', __name__)


@main_bp.route('/', methods=['GET', 'POST'])
def index():
    """
    主页视图函数，处理电影列表展示和添加新电影
    支持GET和POST两种请求方式
    GET: 展示电影列表
    POST: 添加新电影
    """
    # 如果是POST请求，处理添加电影的逻辑
    if request.method == 'POST':
        # 检查用户是否已登录，未登录则跳转到登录页面
        if not current_user.is_authenticated:
            return redirect(url_for('auth.login'))

        # 从表单获取电影标题和年份
        title = request.form.get('title')
        year = request.form.get('year')
        
        # 验证输入数据的有效性
        if not title or not year or len(year) > 4 or len(title) > 60:
            # 输入无效，闪现错误消息并重定向回主页
            flash('Invalid input.')
            return redirect(url_for('main.index'))
            
        # 创建电影对象并保存到数据库
        movie = Movie(title=title, year=year)
        db.session.add(movie)
        db.session.commit()
        # 闪现成功消息并重定向回主页
        flash('Item created.')
        return redirect(url_for('main.index'))

    # GET请求，获取所有电影并渲染模板
    movies = db.session.execute(select(Movie)).scalars().all()
    return render_template('index.html', movies=movies)


@main_bp.route('/movie/edit/<int:movie_id>', methods=['GET', 'POST'])
@login_required  # 登录保护装饰器，只有登录用户才能访问
def edit(movie_id):
    """
    编辑电影视图函数
    
    Args:
        movie_id (int): 要编辑的电影ID
        
    Returns:
        template: GET请求返回编辑页面，POST请求处理更新后重定向到主页
    """
    # 根据ID获取电影对象，如果不存在则返回404错误
    movie = db.get_or_404(Movie, movie_id)

    # 如果是POST请求，处理更新电影的逻辑
    if request.method == 'POST':
        # 从表单获取并清理电影标题和年份
        title = request.form.get('title').strip()
        year = request.form.get('year').strip()

        # 验证输入数据的有效性
        if not title or not year or len(year) != 4 or len(title) > 60:
            # 输入无效，闪现错误消息并重定向回编辑页面
            flash('Invalid input.')
            return redirect(url_for('main.edit', movie_id=movie_id))

        # 更新电影信息并提交到数据库
        movie.title = title
        movie.year = year
        db.session.commit()
        # 闪现成功消息并重定向到主页
        flash('Item updated.')
        return redirect(url_for('main.index'))

    # GET请求，渲染编辑页面
    return render_template('edit.html', movie=movie)


@main_bp.route('/movie/delete/<int:movie_id>', methods=['POST'])
@login_required  # 登录保护装饰器，只有登录用户才能访问
def delete(movie_id):
    """
    删除电影视图函数
    
    Args:
        movie_id (int): 要删除的电影ID
        
    Returns:
        redirect: 重定向到主页
    """
    # 根据ID获取电影对象，如果不存在则返回404错误
    movie = db.get_or_404(Movie, movie_id)
    # 从数据库删除电影并提交
    db.session.delete(movie)
    db.session.commit()
    # 闪现成功消息并重定向到主页
    flash('Item deleted.')
    return redirect(url_for('main.index'))